#ifndef PW_PBL_CONCEPTS_COMPARE_HPP
#define PW_PBL_CONCEPTS_COMPARE_HPP

#include <type_traits>

namespace pw_pbl::inline Concepts
{
	namespace _concepts
	{
		template <template <typename...> class COMPARE, typename T1, typename T2, typename... TN>
		struct ttAnyTwoIs
		{
			static constexpr bool value = ttAnyTwoIs<COMPARE, T1, T2>::value && ttAnyTwoIs<COMPARE, T1, TN...>::value && ttAnyTwoIs<COMPARE, T2, TN...>::value;
		};

		template <template <typename...> class COMPARE, typename T1, typename T2>
		struct ttAnyTwoIs<COMPARE, T1, T2> : public COMPARE<T1, T2>
		{};

		template <template <typename...> class COMPARE, typename T1, typename T2, typename... TN>
		struct ttAnyTwoHas
		{
			static constexpr bool value = ttAnyTwoHas<COMPARE, T1, T2>::value || ttAnyTwoHas<COMPARE, T1, TN...>::value || ttAnyTwoHas<COMPARE, T2, TN...>::value;
		};

		template <template <typename...> class COMPARE, typename T1, typename T2>
		struct ttAnyTwoHas<COMPARE, T1, T2> : public COMPARE<T1, T2>
		{};
	} // namespace _concepts

	template <template <typename...> class COMPARE, typename... T>
	concept ccAnyTwoHas = _concepts::ttAnyTwoHas<COMPARE, T...>::value;

	template <template <typename...> class COMPARE, typename... T>
	concept ccAnyTwoIs = _concepts::ttAnyTwoIs<COMPARE, T...>::value;

	template <typename... T>
	concept ccNotRepeat = !ccAnyTwoHas<std::is_same, T...>;

} // namespace pw_pbl::inline Concepts

#endif // PW_PBL_CONCEPTS_COMPARE_HPP
